#ifndef _TRANSLATE_
#define _TRANSLATE_

#include "Transformation.h"
#include <cassert>

class Translate: public Transformation{
public:
	Translate(Dof *x, Dof *y, Dof *z);
	Translate(Dof *x, Dof *y, Dof *z, char *_name);
	void applyGLTransform();

	void applyTransformMat(Vec4d *v);
	void applyTransformMat(Mat4d *m);
	void applyDerivativeMat(Dof *d, Vec4d *v);
	void applyDerivativeMat(Dof *d, Mat4d *m);
	void applyDerivativeMat(Dof *d1, Dof *d2, Vec4d *v);
	void applyDerivativeMat(Dof *d1, Dof *d2, Mat4d *v);
protected:
	Mat4d *getTransformMat();
	Mat4d *getDerivativeMat(Dof *d);
	Mat4d *getDerivativeMat(Dof *d1, Dof *d2);
private:
	void init(Dof *x, Dof *y, Dof *z, char *_name);
};

class TranslateX: public Transformation{
public:
	TranslateX(Dof *x);
	TranslateX(Dof *x, char *_name);
	void applyGLTransform();

	void applyTransformMat(Vec4d *v);
	void applyTransformMat(Mat4d *m);
	void applyDerivativeMat(Dof *d, Vec4d *v);
	void applyDerivativeMat(Dof *d, Mat4d *m);
	void applyDerivativeMat(Dof *d1, Dof *d2, Vec4d *v);
	void applyDerivativeMat(Dof *d1, Dof *d2, Mat4d *v);
protected:
	Mat4d *getTransformMat();
	Mat4d *getDerivativeMat(Dof *d);
	Mat4d *getDerivativeMat(Dof *d1, Dof *d2);
private:
	void init(Dof *x, char *_name);
};

class TranslateY: public Transformation{
public:
	TranslateY(Dof *x);
	TranslateY(Dof *x, char *_name);
	void applyGLTransform();

	void applyTransformMat(Vec4d *v);
	void applyTransformMat(Mat4d *m);
	void applyDerivativeMat(Dof *d, Vec4d *v);
	void applyDerivativeMat(Dof *d, Mat4d *m);
	void applyDerivativeMat(Dof *d1, Dof *d2, Vec4d *v);
	void applyDerivativeMat(Dof *d1, Dof *d2, Mat4d *v);
protected:
	Mat4d *getTransformMat();
	Mat4d *getDerivativeMat(Dof *d);
	Mat4d *getDerivativeMat(Dof *d1, Dof *d2);
private:
	void init(Dof *y, char *_name);
};

class TranslateZ: public Transformation{
public:
	TranslateZ(Dof *x);
	TranslateZ(Dof *x, char *_name);
	void applyGLTransform();

	void applyTransformMat(Vec4d *v);
	void applyTransformMat(Mat4d *m);
	void applyDerivativeMat(Dof *d, Vec4d *v);
	void applyDerivativeMat(Dof *d, Mat4d *m);
	void applyDerivativeMat(Dof *d1, Dof *d2, Vec4d *v);
	void applyDerivativeMat(Dof *d1, Dof *d2, Mat4d *v);
protected:
	Mat4d *getTransformMat();
	Mat4d *getDerivativeMat(Dof *d);
	Mat4d *getDerivativeMat(Dof *d1, Dof *d2);
private:
	void init(Dof *z, char *_name);
};

#endif
